// 版权归 瞄你个汪 所有。使用本代码应遵守相关法律法规和Apache 2.0开源许可要求。
package top.geeke.handler;

import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.schema.Column;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import top.geeke.config.SysUserSessionManager;
import top.geeke.config.cache.RedisCache;
import top.geeke.constants.AppCachePool;
import top.geeke.constants.AppConstPool;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 租户处理器
 * </p>
 *
 * @author 瞄你个汪
 * @since 2024/6/2 16:15
 */
@Slf4j
@Component
public class TableTenantLineHandler implements TenantLineHandler {
    @Resource
    private RedisCache redisCache;

    @Resource
    private SysUserSessionManager sessionManager;

    @Override
    public Expression getTenantId() {
        Long tenantId = sessionManager.getTenantId();
        return new StringValue((tenantId == null ? AppConstPool.PRIMARY_ID : tenantId) + "");
    }

    @Override
    public String getTenantIdColumn() {
        return TenantLineHandler.super.getTenantIdColumn();
    }

    @Override
    public boolean ignoreTable(String tableName) {
        if (Strings.isEmpty(tableName)) return true;
        Map<String, Boolean> ignoreMap = getIgnoreTenantMap(getTenantIdColumn());
        return Strings.isEmpty(tableName) || ignoreMap.containsKey(tableName);
    }

    @Override
    public boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {
        // TODO 从用户信息中读取租户id
        return TenantLineHandler.super.ignoreInsert(columns, tenantIdColumn);
    }

    /**
     * 获取租户忽略映射表
     */
    public Map<String, Boolean> getIgnoreTenantMap(String tenantId) {
        return redisCache.getAndSet(AppCachePool.SYSTEM_TENANT_IGNORE_MAP, () -> {
            Map<String, Boolean> map = new HashMap<>();
            List<TableInfo> tableInfos = TableInfoHelper.getTableInfos();
            for (TableInfo table : tableInfos) {
                if (table.getFieldList().stream().noneMatch(x -> tenantId.equals(x.getColumn())))
                    map.put(table.getTableName(), true);
            }
            return map;
        });
    }
}
